package com.guochuang.yunwang.promanager.controller;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.guochuang.yunwang.promanager.annotation.CancelLoginIntercept;
import com.guochuang.yunwang.promanager.domain.Group;
import com.guochuang.yunwang.promanager.domain.Role;
import com.guochuang.yunwang.promanager.domain.User;
import com.guochuang.yunwang.promanager.domain.UserGroup;
import com.guochuang.yunwang.promanager.domain.dto.group.GroupDTO;
import com.guochuang.yunwang.promanager.domain.dto.group.GroupManageDTO;
import com.guochuang.yunwang.promanager.domain.vo.group.GroupManageVO;
import com.guochuang.yunwang.promanager.domain.vo.group.GroupSearchVO;
import com.guochuang.yunwang.promanager.domain.vo.group.GroupUserVO;
import com.guochuang.yunwang.promanager.domain.vo.group.GroupVO;
import com.guochuang.yunwang.promanager.service.GroupService;
import com.guochuang.yunwang.promanager.service.RoleService;
import com.guochuang.yunwang.promanager.service.UserGroupService;
import com.guochuang.yunwang.promanager.service.UserService;
import com.guochuang.yunwang.promanager.utils.ProjectConstant;
import com.guochuang.yunwang.promanager.utils.ResultEntity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@RestController
@Api(value = "团队接口", tags = "团队接口")
public class GroupController {
    /**
     * 自动注入部分
     */
    @Autowired
    private SimpleDateFormat simpleDateFormat;
    @Autowired
    private GroupService groupService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserGroupService userGroupService;
    @Autowired
    private RoleService roleService;

    @GetMapping(value = "/get/group/users/{gid}")
    @ApiOperation(value = "获取团队中的所有人员")
    public ResultEntity getGroupUsersList(@PathVariable Integer gid) {

        List<GroupUserVO> res = userGroupService.getGroupUsersList(gid);

        return ResultEntity.successWithData(res);
    }

    /**
     * 添加接口
     *
     * @param group
     * @return
     */
    @PostMapping(value = "/add/new/group")
    @ApiOperation(value = "以Group对象直接添加新的团队")
    @CancelLoginIntercept
    public ResultEntity addNewGroup(@RequestBody Group group) {
        String now = simpleDateFormat.format(new Date());
        group.setGmtCreate(now);
        group.setGmtModified(now);

        Integer res = groupService.addNewGroup(group);

        if (res > 0) {
            return ResultEntity.successWithoutData();
        } else {
            return ResultEntity.failed(ProjectConstant.USER_ADD_FAILED);
        }
    }

    @PostMapping(value = "/add/vo/group")
    @ApiOperation(value = "通过GroupVo添加一个团队，团队leader姓名需要预先存在")
    @CancelLoginIntercept
    public ResultEntity addGroupVo(@RequestBody GroupVO groupVo) {
        // add a Group
        Group group = new Group();
        group.setGname(groupVo.getGname());
        group.setGnums(1);

        ResultEntity res = this.addNewGroup(group);
        if (!res.getResult().equals(ResultEntity.success)) {
            return res;
        }

        // add a UserGroup
        Group temp = groupService.getGroupByName(groupVo.getGname());
        UserGroup ug = new UserGroup();
        User u = userService.findUserByName(groupVo.getGLeaderName());

        ug.setUid(u.getUid());
        ug.setGid(temp.getGid());
        ug.setRid(1);
        ug.setIsDeleted(0);

        String now = simpleDateFormat.format(new Date());
        ug.setGmtCreate(now);
        ug.setGmtModified(now);

        Integer i = userGroupService.addUserGroup(ug);
        if (i > 0) {
            return ResultEntity.successWithoutData();
        } else {
            return ResultEntity.failed(ProjectConstant.GROUP_ADD_FAILED);
        }
    }

    /**
     * 修改接口
     *
     * @param group
     * @return
     */
    @PutMapping(value = "/update/group/by/gid")
    @ApiOperation(value = "根据id修改团队")
    @CancelLoginIntercept
    public ResultEntity updateGroupById(@RequestBody Group group) {
        String now = simpleDateFormat.format(new Date());
        group.setGmtModified(now);

        Integer res = groupService.updateGroup(group);
        if (res > 0) {
            return ResultEntity.successWithoutData();
        } else {
            return ResultEntity.failed(ProjectConstant.GROUP_CHANGE_FAILED);
        }
    }

    @PutMapping("/manage/user/in/group")
    @ApiOperation(value = "修改成员属性: 是否在当前团队中")
    @CancelLoginIntercept
    public ResultEntity manageUserInGroup(@RequestBody GroupManageVO groupManageVO) {
        User u = userService.findUserByName(groupManageVO.getUserName());
        Group g = groupService.getGroupByName(groupManageVO.getGroupName());

        UserGroup ug = new UserGroup();
        ug.setUid(u.getUid());
        ug.setGid(g.getGid());

        Integer isDeleted = groupManageVO.getIsInGroup() ? 0 : 1;
        ug.setIsDeleted(isDeleted);

        String now = simpleDateFormat.format(new Date());
        ug.setGmtModified(now);

        Integer res = userGroupService.updateUserGroup(ug);
        if (res > 0) {
            return ResultEntity.successWithoutData();
        } else {
            return ResultEntity.failed(ProjectConstant.USER_CHANGE_FAILED);
        }
    }

    /**
     * 删除接口
     *
     * @param id
     * @return
     */
    @DeleteMapping(value = "/del/group/by/{gid}")
    @ApiOperation(value = "根据id(PathVariable方式)删除单个团队")
    @CancelLoginIntercept
    public ResultEntity deleteGroupById(@PathVariable Integer id) {
        Integer res = groupService.deleteGroupById(id);
        if (res > 0) {
            return ResultEntity.successWithoutData();
        } else {
            return ResultEntity.failed(ProjectConstant.USER_DELETE_FAILED);
        }
    }

    @DeleteMapping(value = "/del/groups/by/gids")
    @ApiOperation(value = "根据id批量删除团队")
    @CancelLoginIntercept
    public ResultEntity deleteGroupByIds(@RequestBody List<Integer> gids) {
        Integer res = groupService.deleteGroupByIds(gids);

        if (res > 0) {
            return ResultEntity.successWithoutData();
        } else {
            return ResultEntity.failed(ProjectConstant.USER_DELETE_FAILED);
        }
    }

    @DeleteMapping(value = "/del/groups/by/names")
    @ApiOperation(value = "根据团队名称批量删除团队")
    @CancelLoginIntercept
    public ResultEntity deleteGroupsByNames(@RequestBody List<String> names) {
        Integer gid = null;
        Integer res = null;
        UserGroup ug = null;
        Group g = null;
        String now = null;

        for (String name : names) {
            g = groupService.getGroupByName(name);
            if (g.getGnums() > 0) {
                return ResultEntity.failed(ProjectConstant.USER_DELETE_FAILED);
            }
        }

        for (String name : names) {
            g = groupService.getGroupByName(name);
            gid = g.getGid();
            ug = userGroupService.getUserGroupByGId(gid);

            groupService.deleteGroupByName(name);
            now = simpleDateFormat.format(new Date());
            ug.setGmtModified(now);
            ug.setIsDeleted(1);
            userGroupService.updateUserGroup(ug);
        }

        return ResultEntity.successWithoutData();
    }

    @DeleteMapping(value = "/del/group/by/name")
    @ApiOperation("根据团队名称删除团队")
    @CancelLoginIntercept
    public ResultEntity deleteGroupByName(@RequestParam("gname") String gname) {
        Group g = groupService.getGroupByName(gname);
        if (g.getGnums() > 0) {
            return ResultEntity.failed(ProjectConstant.USER_DELETE_FAILED);
        }

        Integer gid = g.getGid();

        Integer i = groupService.deleteGroupByName(gname);

        if (i > 0) {
            UserGroup ug = userGroupService.getUserGroupByGId(gid);

            String now = simpleDateFormat.format(new Date());
            ug.setGmtModified(now);
            ug.setIsDeleted(1);
            userGroupService.updateUserGroup(ug);

            return ResultEntity.successWithoutData();
        } else {
            return ResultEntity.failed(ProjectConstant.USER_DELETE_FAILED);
        }
    }

    /**
     * 查询接口
     *
     * @param gid
     * @return
     */
    @GetMapping(value = "/get/group/by/{gid}")
    @ApiOperation(value = "根据id查询团队")
    @CancelLoginIntercept
    public ResultEntity getGroupById(@PathVariable Integer gid) {
        Group g = groupService.getGroupById(gid);
        return g != null ? ResultEntity.successWithData(g) : ResultEntity.failed(ProjectConstant.USER_FAILED_MESSAGE);
    }

    @GetMapping(value = "/get/groups/by/page/{page}/{offset}")
    @ApiOperation(value = "对所有团队进行分页查询")
    @CancelLoginIntercept
    public ResultEntity getGroupsByPage(@PathVariable Integer page,
                                        @PathVariable Integer offset) {
        PageHelper.startPage(page, offset);
        List<Group> li = groupService.getAllGroups();
        PageInfo<Group> gps = new PageInfo<>(li);

        Map<String, Object> rec = new HashMap<>();
        rec.put("total", gps.getTotal());
        rec.put("data", gps.getList());
        return ResultEntity.successWithData(rec);
    }

    @GetMapping(value = "/get/groupdtos/by/page/{page}/{offset}")
    @ApiOperation(value = "分页查询并返回GroupDTO对象")
    @CancelLoginIntercept
    public ResultEntity getGroupDtosByPage(@PathVariable Integer page,
                                           @PathVariable Integer offset) {
        PageHelper.startPage(page, offset);
        List<GroupDTO> li = groupService.getAllGroupDTOs();
        PageInfo<GroupDTO> gps = new PageInfo<>(li);

        Map<String, Object> rec = new HashMap<>();
        rec.put("total", gps.getTotal());
        rec.put("data", gps.getList());
        return ResultEntity.successWithData(rec);
    }

    @GetMapping(value = "/get/group/statistics")
    @ApiOperation(value = "回传统计数据，包括角色和其对应的数量")
    @CancelLoginIntercept
    public ResultEntity getGroupStatistics(@RequestParam("gname") String groupName) {
        Group g = groupService.getGroupByName(groupName);
        Map<String, Long> map = new HashMap<>();

        List<Integer> rids = userGroupService.selectAllRidsByGid(g.getGid());

        Role r = null;

        for (Integer id : rids) {
            r = roleService.getRoleById(id);

            if (!map.containsKey(r.getRname())) {
                map.put(r.getRname(), 1L);
            } else {
                Long i = map.get(r.getRname());
                ++i;
                map.put(r.getRname(), i);
            }
        }

        List<Map<String, String>> li = new ArrayList<>();
        Map<String, String> temp;

        for (Map.Entry<String, Long> e : map.entrySet()) {
            temp = new HashMap<>();
            temp.put("value", e.getValue().toString());
            temp.put("name", e.getKey());

            li.add(temp);
        }

        String json = JSON.toJSONString(li);

        return ResultEntity.successWithData(json);
    }

    @GetMapping(value = "/get/users/in/group")
    @ApiOperation(value = "在当前团队中的人员信息直接返回给前端")
    @CancelLoginIntercept
    public ResultEntity getUsersInGroup(@RequestParam("gname") String groupName) {
        Group g = groupService.getGroupByName(groupName);
        List<GroupManageDTO> inGroup = userGroupService.selectGroupManageDTOsInGroupByGid(g.getGid());
        String json = JSON.toJSONString(inGroup);
        return ResultEntity.successWithData(json);
    }

    @GetMapping(value = "/get/users/not/in/group")
    @ApiOperation(value = "不在当前团队中的人员信息直接返回给前端")
    @CancelLoginIntercept
    public ResultEntity getUsersNotInGroup(@RequestParam("gname") String groupName) {
        Group g = groupService.getGroupByName(groupName);

        List<GroupManageDTO> inGroup = userGroupService.selectGroupManageDTOsInGroupByGid(g.getGid());
        List<GroupManageDTO> allGroup = userGroupService.selectAllGroupManageDTOs();

        allGroup.removeAll(inGroup);

        String json = JSON.toJSONString(allGroup);
        return ResultEntity.successWithData(json);
    }

    @GetMapping(value = "/get/users/in/and/not/in/group")
    @ApiOperation(value = "统一将在/不在当前团队中的人员信息直接返回给前端")
    @CancelLoginIntercept
    public ResultEntity getUsersInGroupAndNot(@RequestParam("gname") String groupName) {
        Group g = groupService.getGroupByName(groupName);

        List<GroupManageDTO> inGroup = userGroupService.selectGroupManageDTOsInGroupByGid(g.getGid());
        List<GroupManageDTO> allGroup = userGroupService.selectAllGroupManageDTOs();
        allGroup.removeAll(inGroup);

        Map<String, Object> map = new HashMap<>();
        map.put("inGroup", inGroup);
        map.put("notInGroup", allGroup);

        return ResultEntity.successWithData(map);
    }

    @PostMapping(value = "/get/group/like")
    @ApiOperation(value = "模糊查询得到一批GroupDTO对象，并分页")
    @CancelLoginIntercept
    public ResultEntity getGroupLike(@RequestBody GroupSearchVO group) {
        PageHelper.startPage(group.getPage(), group.getOffset());
        List<GroupDTO> li = groupService.getAllGroupDTOsLike(group);

        PageInfo<GroupDTO> gps = new PageInfo<>(li);

        Map<String, Object> rec = new HashMap<>();
        rec.put("total", gps.getTotal());
        rec.put("data", gps.getList());
        return ResultEntity.successWithData(rec);
    }

    @GetMapping(value = "/get/all/user/names")
    @ApiOperation(value = "获取所有用户姓名")
    @CancelLoginIntercept
    public ResultEntity getAllUserNames() {
        List<String> li = groupService.getAllUserNames();
        String json = JSON.toJSONString(li);
        return ResultEntity.successWithData(json);
    }


}
